#include "GameTable.h"
#include <iostream>
#include <Windows.h>
#include <string>

//Initialize the gameTable by Initializing every objects that it contains.
//That is a deck, a hand, a devil pile, 7 columns piles and 8 stack piles.
void Initialize(gameTable& gt)
{
	Initialize(gt.gameDeck, DECK_XPOS, DECK_YPOS, false);
	Initialize(gt.gameHand, HAND_XPOS, HAND_YPOS, true);
	Initialize(gt.gameDevils, DEVIL, DEVILS_XPOS, DEVILS_YPOS);
	for (int i = 0; i < 7; i++)
	{
		pile column;
		Initialize(column, COLUMN, i*COLUMNS_SPACE+COLUMNS_XPOS, COLUMNS_YPOS, i);
		gt.gameColumns[i] = column;
	}
	for (int j = 0; j < 8; j++)
	{
		pile stack;
		Initialize(stack, STACK, j*STACKS_SPACE+STACKS_XPOS, STACKS_YPOS, j);
		gt.gameStacks[j] = stack;
	}
	Populate(gt);
}

//Fills the columns and devils for the game. Also place a card in the hand immediately, for convenience sake.
void Populate(gameTable& gt)
{
	//Fill the columns following the sequential rules
	//First column gets 1 card, second column gets 2 cards [...] 7th column gets 7 cards
	for (int i = 0; i < 7; i++)
	{
		for (int j = 0; j <= i; j++)
		{
			//If we're dealing with the last card of the column we flip it, otherwise it stays facedown cause the deck is face down initially.
			if (j == i)
			{
				Transfert(gt.gameDeck, gt.gameColumns[i], true);
			}
			else
			{
				Transfert(gt.gameDeck, gt.gameColumns[i]);
			}
		}
	}
	//Fill the devils with 7 cards
	for (int i = 0; i < 7; i++)
	{
		Transfert(gt.gameDeck, gt.gameDevils, true);
	}
	//Puts a card in the hand
	Transfert(gt.gameDeck, gt.gameHand, true);
}

//This is the function that handle how the gameTable is displayed in the console window.
//It starts by cleaning the screen.
//It then calls display on every objects within the table, which are the Deck/Hand/Devils/Stacks/Columns objects.
//It then place a string for every object type around the table and voila.
void Display(const gameTable& gt)
{
	ClearScreen(char(219));
	Display(gt.gameDeck);
	Display(gt.gameHand);
	Display(gt.gameDevils);
	for (int j = 0; j < 8; j++)
	{
		PlaceString(WRAPPER, j * STACKS_SPACE + WRAPPER_STACKS_XPOS, WRAPPER_STACKS_YPOS);
		Display(gt.gameStacks[j]);
	}
	for (int i = 0; i < 7; i++)
	{
		PlaceString(WRAPPER, i * COLUMNS_SPACE + WRAPPER_COLUMNS_XPOS, WRAPPER_COLUMNS_YPOS);
		Display(gt.gameColumns[i]);
	}
	PlaceString(S_STACKS, S_STACKS_XPOS, S_STACKS_YPOS);
	PlaceString(S_COLUMNS, S_COLUMNS_XPOS, S_COLUMNS_YPOS);
	PlaceString(S_DECK, S_DECK_XPOS, S_DECK_YPOS);
	PlaceString(S_HAND, S_HAND_XPOS, S_HAND_YPOS);
	PlaceString(S_DEVILS, S_DEVILS_XPOS, S_DEVILS_YPOS);
	SetCursorPosition(20, 24);
}



//Fills the screen with a specified char
void FillScreen(const char& ch, int xPos, int yPos, int width, int height)
{
	for (int x = xPos; x < width + xPos; x++)
	{
		for (int y = yPos; y < height + yPos; y++)
		{
			SetCursorPosition(x, y);
			std::cout << ch;
		}
	}
}

//Clears the screen
void ClearScreen(const char& ch)
{
	for (int x = 0; x < 80; x++)
	{
		for (int y = 0; y < 25; y++)
		{
			SetCursorPosition(x, y);
			std::cout << ch;
		}
	}
}

//Places a string at specified position
void PlaceString(const std::string& str, int xPos, int yPos)
{
	SetCursorPosition(xPos, yPos);
	std::cout << str;
}

bool IsValid(char origin[2], char destination[2])
{
	bool isValid = false;
	//If the origin and the destinations aren't the same, check if the type to type transfert is a "legit" move
	if (origin[0] != destination[0] || origin[1] != destination[1])
	{
		for (int i = 0; i < MAX_LEGIT_MOVES; i++)
		{
			if (origin[0] == LEGIT_MOVES[i][0] && destination[1] == LEGIT_MOVES[i][1])
			{
				isValid = true;
			}
		}
	}
	return isValid;
}